package hu.vaes_dot_hrak.szoftlab4;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Field {

	private HashMap<Constant.Way, Field> neighbours = new HashMap<Constant.Way, Field>();

	private AntKillerToxic antKillerToxic;

	private int antSmell;
	private int foodSmell;
	private int antHillSmell;
	private List<FieldElement> elements = new ArrayList<FieldElement>();

	public Field(int antHillSmell) {
		this.antHillSmell = antHillSmell;
		antKillerToxic = new AntKillerToxic();
	}

	public void addElement(FieldElement element) {
		elements.add(element);
	}

	public void removeElement(FieldElement element) {
		elements.remove(element);
	}

	public Field getNeighboorOnWay(Constant.Way way) {
		return neighbours.get(way);
	}

	public boolean isOnSteppable() {
		for (FieldElement actualElement : elements) {
			if (actualElement != null)
				if (!actualElement.isOnStepable())
					return false;
		}
		return true;
	}

	public int getAntSmell() {
		return this.antSmell;
	}

	public void modifyAntSmell(int plusAntSmellValue) {
		this.antSmell += plusAntSmellValue;
		if (this.antSmell < 0)
			this.antSmell = 0;
	}

	public int getFoodSmell() {
		return this.foodSmell;
	}

	public void antStepIn(Ant ant, int antSmell) {
		addElement(ant);
		ant.storeAntSmell();
		antSmell += antSmell;
		for (FieldElement actualElement : elements) {
			if (actualElement != null)
				actualElement.onStep(ant);
		}
		if (isAntKillerToxic()) {
			ant.die();
		}
	}

	public void antStepOut(Ant ant) {
		removeElement(ant);
	}

	public void spinyAntEaterStepIn(SpinyAntEater spinyAntEater) {
		addElement(spinyAntEater);

		for (FieldElement actualElement : elements) {
			if (actualElement != null) {
				if (actualElement.spinyAntEaterTryToEat())
					spinyAntEater.increaseEatedAnts();
			}
		}
	}

	public void spinyAntEaterStepOut(SpinyAntEater spinyAntEater) {
		removeElement(spinyAntEater);
	}

	public boolean isAntKillerToxic() {
		return antKillerToxic.isToxic();
	}

	public boolean onStepableForSpinyAntEater(Constant.Way way) {
		boolean isStoneHere = false; // van-e kavics
		for (FieldElement actualElement : elements) {
			if (actualElement != null) {
				isStoneHere = isStoneHere || actualElement.isPushable();
			}
		}
		if (isStoneHere) {
			boolean isStoneNextField = false; // van-e kavics
			for (FieldElement actualElement : getNeighboorOnWay(way)
					.getElements()) {
				if (actualElement != null) {
					isStoneNextField = isStoneNextField
							|| actualElement.isPushable();
				}
			}
			if (isStoneNextField) {
				int result3 = 0;
				for (FieldElement actualElement : getNeighboorOnWay(way)
						.getNeighboorOnWay(way).getElements()) {
					if (actualElement != null) {
						result3 += actualElement.stonePushableToThis();
					}
				}
				if (result3 == 0) {
					return true;
				} else {
					return false;
				}
			} else {
				int pushableElements = 0;
				for (FieldElement actualElement : getNeighboorOnWay(way)
						.getElements()) {
					if (actualElement != null) {
						pushableElements += actualElement.stonePushableToThis();
					}
				}
				if (pushableElements == 0) {
					return true;
				} else {
					return false;
				}
			}
		} else {
			return true;
		}

	}

	public void setAntKillerToxic(int toxicTime, int radius) {
		if (radius > 0) {
			this.antKillerToxic.setToxic(true);
			antKillerToxic.setToxicTime(toxicTime);
			if (neighbours.get(Constant.Way.UP) != null)
				neighbours.get(Constant.Way.UP).setAntKillerToxic(toxicTime,
						radius - 1);
			if (neighbours.get(Constant.Way.DOWN) != null)
				neighbours.get(Constant.Way.DOWN).setAntKillerToxic(toxicTime,
						radius - 1);
			if (neighbours.get(Constant.Way.RIGHTTOP) != null)
				neighbours.get(Constant.Way.RIGHTTOP).setAntKillerToxic(
						toxicTime, radius - 1);
			if (neighbours.get(Constant.Way.LEFTTOP) != null)
				neighbours.get(Constant.Way.LEFTTOP).setAntKillerToxic(
						toxicTime, radius - 1);
			if (neighbours.get(Constant.Way.LEFTDOWN) != null)
				neighbours.get(Constant.Way.LEFTDOWN).setAntKillerToxic(
						toxicTime, radius - 1);
			if (neighbours.get(Constant.Way.RIGHTDOWN) != null)
				neighbours.get(Constant.Way.RIGHTDOWN).setAntKillerToxic(
						toxicTime, radius - 1);
			for (FieldElement actualElement : elements) {
				actualElement.onAntKillerToxic();
			}
		}
	}

	public void setAntSmellNeutralizeToxic(int radius) {
		if (radius > 0) {
			this.cleanAntSmell();
			if (neighbours.get(Constant.Way.UP) != null)
				neighbours.get(Constant.Way.UP).setAntSmellNeutralizeToxic(
						radius - 1);
			if (neighbours.get(Constant.Way.DOWN) != null)
				neighbours.get(Constant.Way.DOWN).setAntSmellNeutralizeToxic(
						radius - 1);
			if (neighbours.get(Constant.Way.RIGHTTOP) != null)
				neighbours.get(Constant.Way.RIGHTTOP)
						.setAntSmellNeutralizeToxic(radius - 1);
			if (neighbours.get(Constant.Way.LEFTTOP) != null)
				neighbours.get(Constant.Way.LEFTTOP)
						.setAntSmellNeutralizeToxic(radius - 1);
			if (neighbours.get(Constant.Way.RIGHTDOWN) != null)
				neighbours.get(Constant.Way.RIGHTDOWN)
						.setAntSmellNeutralizeToxic(radius - 1);
			if (neighbours.get(Constant.Way.LEFTDOWN) != null)
				neighbours.get(Constant.Way.LEFTDOWN)
						.setAntSmellNeutralizeToxic(radius - 1);
		}
	}

	public void cleanAntSmell() {
		this.antSmell = 0;
	}

	public int getAntHillSmell() {
		return antHillSmell;
	}

	public AntKillerToxic getAntKillerToxic() {
		return antKillerToxic;
	}

	public HashMap<Constant.Way, Field> getNeighbours() {
		return neighbours;
	}

	public List<FieldElement> getElements() {
		return elements;
	}

	public void pushStoneToHere(Constant.Way way) {
		for (FieldElement actualElement : elements) {
			if (actualElement != null) {
				actualElement.pushedStone(way);
			}
		}
	}

}
